;   This program is free software: you can redistribute it and/or modify
;   it under the terms of the GNU General Public License as published by
;   the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.
;
;   This program is distributed in the hope that it will be useful,
;   but WITHOUT ANY WARRANTY; without even the implied warranty of
;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;   GNU General Public License for more details.
;
;   You should have received a copy of the GNU General Public License
;   along with this program.  If not, see <http://www.gnu.org/licenses/>.
; 
;
;--------- register_display ------------
;
;Q. 98楼
;http://tieba.baidu.com/p/3740277941?pn=3

;问题:
;现在一个现实问题，大部分初学者，不知道各寄存器的值！
;希望写一个打印各寄存器值的程序！不要中断，不要32位汇编！
;就像C语言里面的printf函数！
;
;回答:
;列印寄存器的值和列印一般资料没什么分别
;和列印16bit/32bit的hex值一样.........
;
;其实进入debug ,按R,就是16bit寄存器的值
;这个代码正是仿debug [R]的作法,印出各寄存器和Flag的值
;但这个不是真正的debug,没有单步,所以CS:IP和flag等,知道了也没什么意义.
;倒是可以看看程式被载入时各寄存器的初始值
;
;
doc_att         equ     07h
reg_att         equ     1eh
mode_add        equ     0b800h
modeX           equ     0
now_page        equ     0

;------------------------------------------------------------------------------
@print_String   MACRO   offst,row,col,att,len,address,write_modeX
                LOCAL ps50              ;direct output to video address

                push    ds
                push    es
                push    bp
                mov     bp,address
                mov     es,bp
                mov     cx,len
                lea     si,offst
                xor     ax,ax
                mov     al,row
                shl     ax,1
                shl     ax,1
                add     al,row
                shl     ax,1    ;10
                shl     ax,1    ;20
                shl     ax,1    ;40
                shl     ax,1    ;80
                shl     ax,1    ;160     80 * 2
                shl     dl,1
                add     al,col
                mov     di,ax
                mov     ah,write_modeX
                cmp     ah,1
                mov     ah,att
                jnz     ps50
                add     si,cx
ps50:           lodsb
                stosw
                loop    ps50

                pop     bp
                pop     es
                pop     ds

                ENDM
;------------------------------------------------------------------------------
@display        macro   offst,row,col,att,len,write_modeX,page,write_mode
                LOCAL dis10

                IFNB    <page>
    	        mov	bh,page
		ELSE
                xor	bh,bh
		ENDIF
                IFNB    <len>
                mov     cx,len
		ELSE
                mov     cx,0ffffh
                lea     di,offst
                xor     al,al
                cld
                repnz   scasb
                neg     cx
                dec     cx
                ENDIF
                IFNB    <col>
                mov     dl,col
                ENDIF
                IFNB    <row>
                mov     dh,row
                ENDIF
                IFNB    <write_mode>
                mov     al,write_mode
		ELSE
                xor     al,al
		ENDIF
                IFNB    <att>
                mov     bl,att
		ELSE
                xor     bl,07h
		ENDIF
                lea     bp,offst
                mov     ah,write_modeX
                cmp     ah,1
                jnz     dis10
                add     bp,cx
dis10:          mov     ah,13h
                int     10h
                endm
;------------------------------------------------------------------------------
DATAS SEGMENT

sp_flag         db      0
Pre_ax          dw      0
pre_bx          dw      0
pre_cx          dw      0
pre_dx          dw      0

pre_sp          dw      0
pre_bp          dw      0
pre_si          dw      0
pre_di          dw      0

pre_ds          dw      0
pre_es          dw      0
pre_ss          dw      0
pre_cs          dw      0
pre_ip          dw      0
pre_flag        dw      0

print_time      db      0

line1           db '   AX=      BX=      CX=      DX=      SP=      BP=      SI=      DI=           '
line1_L         equ     $ - offset line1
line2           db '   DS=      ES=      SS=      CS=      IP=                                      '
line2_L         equ     $ - offset line2
flag_0          db      'NV','UP','EI','NT','PL','NZ','NA','PO','NC'
flag_L          equ     $ - offset flag_0
flag_1          db      'OV','DN','DI','TR','NG','ZR','AC','PE','CY'
flag_data	db	27 dup (' ')
flag_data_L	equ	$ - offset flag_data

DATAS ENDS

STACK SEGMENT STACK
DB 100 DUP(0)
stack_end equ $
STACK ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACK

start:          jmp     short s10

old_ss          dw      0
old_sp          dw      0
old_ax          dw      0
old_ip          dw      0
old_cs          dw      0

s10:            mov     cs:old_ax,ax
                call    s20

s20:            pop     ax      ;get current ip
                sub     ax,(offset s20 - offset start) ;get start offset
                mov     cs:old_ip,ax
                mov     ax,cs
                mov     cs:old_cs,ax
                ;
                mov     cs:old_ss,ss
                mov     cs:old_sp,sp
                mov     ax,stack
                cli
                mov     ss,ax
                mov     sp,offset stack_end
                sti

                pushf
                push    ds
                mov     ax,datas
                mov     ds,ax

                mov     pre_bx,bx
                mov     pre_cx,cx
                mov     pre_dx,dx
                mov     pre_si,si
                mov     pre_di,di
                mov     pre_bp,bp
                mov     ax,es
                mov     pre_es,ax

                pop     ax
                mov     pre_ds,ax
                pop     ax  ;flag
                mov     pre_flag,ax
                ;
                mov     ax,cs:old_ss
                mov     pre_ss,ax
                mov     ax,cs:old_sp
                mov     pre_sp,ax
                mov     ax,cs:old_ax
                mov     pre_ax,ax
                mov     ax,cs:old_ip
                mov     pre_ip,ax
                mov     ax,cs:old_cs
                mov     pre_cs,ax


                ;call    cls
                ;
                call    print_head
 
key:            xor     ah,ah
                int     16h
                mov     ah,4ch
                int     21H
;------------------------------------------------------------------------------
print_head:
                @print_String line1,0,0,reg_att,line1_L,mode_add,0
                @print_String line2,1,0,reg_att,line2_L,mode_add,0
                ;call    print_foot
                mov     dx,0006h   ;first line
                mov     bp,8       ;8 regs
                mov     print_time,2
                mov     si,offset pre_ax
pd10:           push    dx
                call    setcur
                mov     dx,[si]
                call    print_hex
                pop     dx
                add     dl,9
                inc     si
                inc     si
                dec     bp
                jnz     pd10
                dec     print_time
                jz      pd20
                mov     bp,5        ;next 5 regs
                mov     dx,0106h    ;second line
                jmp     short pd10
pd20:           call    print_flag
                ret
;------------------------------------------------------------------------------
print_flag:     push    es
                push    ds
                pop     es
                mov     dx,pre_flag
                mov     si,offset flag_0
                mov     di,offset flag_data
                mov     bx,flag_L
                mov     cl,4
                shl     dx,cl
                mov     cx,6
                mov     bp,1
                call    change_flag1
                mov     cx,3
                mov     bp,0
                call    change_flag
                @display flag_data,1,48,reg_att,flag_data_L,0
                pop     es
		ret
;------------------------------------------------------------------------------
change_flag:    shl     dx,1
change_flag1:   shl     dx,1
                jc      ch10
                mov     ax,[si]
                jmp     short ch20
ch10:           mov     ax,[si+bx]
ch20:           stosw
                inc     di
                inc     si
                inc     si
                dec     cx
                jz      ch40
                cmp     bp,0
                jnz     change_flag1
                jmp     short change_flag
ch40:           ret
;------------------------------------------------------------------------------
print_hex:      ;word in dx
                mov     ch,4
                jmp     pr5
print_hex1:     mov     ch,2
pr5:            mov     bh,now_page
                mov     bl,doc_att
                mov     ah,0eh
pr10:           mov     cl,4
                rol     dx,cl
                mov     al,dl
                and     al,00001111b   ; char
                add     al,'0'
                cmp     al,'9'
                jbe     pr20
                add     al,7
pr20:           int     10h
                dec     ch
                jnz     pr10
                ret
;------------------------------------------------------------------------------
cls:		mov	ah,0fh                  ;get display mode to al
		int	10h
		mov	ah,0                    ;Set display mode
		int	10h
		ret
;------------------------------------------------------------------------------
SetCur:         mov     bh,now_page
                mov     ah,2
                int     10h
                ret
;------------------------------------------------------------------------------
CODES ENDS
END START